Word2Vec으로 문장 분류하기_180415_12_45.html @ 단어 임베딩 방법론 가운데 하나인 Word2Vec을 활용할것이다. Word2Vec 을 이용하여 문장을 분류하는 방법에 대해 살펴볼 것이다. 휴대폰 리뷰사이트에 있는 스마트폰 리뷰들을 분석해 볼 것이다. 리뷰1: 발열은 LTE폰의 숙명 ㅠㅠ 리뷰2: HD촬영기능 하나만으로도 충분히 만족하시리라 봅니다~~ 리뷰1을 작성한 사용자는 배터리를 휴대폰의 중요한 기능이라고 생각하는 모양이다. 리뷰2의 경우엔 카메라일 것이다. 이렇게 리뷰가 하나 주어졌을 때 해당 리뷰를 작성한 사용자가 휴대폰의 어떤 기능을 중시하는지를 알아맞혀 보고 싶은 것이다. 다시 말해 휴대폰 리뷰 문장을 ‘배터리’, ‘카메라’, ‘디자인’, ‘사운드’ 따위의 class 로 classification 하는 문제가 될 것이다. 사람이 리뷰를 하나하나 읽어보면서 확인해도 되지만 우리는 컴퓨터의 힘을 빌려보겠다. @ Word2Vec 를 사용하여 단어를 벡터로 바꾸기(You embed words into vector) img d9b3d038-c239-4cd6-b8c2-68619631dfa1 Word2Vec이라는 방법론은 2013년 구글에서 개발되었다. 단어(Word)를 벡터(Vector)로 바꿔주는 방법이다. 이를 임베딩(Embedding)이라고 한다. Word2Vec을 정확하게 이해하려면 논문을 읽으면 된다. https://arxiv.org/pdf/1301.3781.pdf Word2Vec 학습 방식에 관심이 있으신 분은 이곳을 방문하면 된다. https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/03/30/word2vec/ GloVe, Fasttext 같은 다른 방법론과의 비교에 관심 있으시면 이곳을 방문하면 된다. https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/03/11/embedding/ Word2Vec의 효과는 놀랍다. 단어를 벡터화할 때 단어의 문맥적 의미를 보존하기 때문이다. 위의 그림처럼 MAN과 WOMAN 사이의 거리는 KING과 QUEEN 거리와 유사하다. 벡터로 바뀐 단어들은 ‘유클리디안 거리’, ‘코사인 유사도’ 와 같은 방식들로 그 거리를 잴 수 있다. 그 거리가 가까울(작을) 경우 의미가 비슷한 단어라고 해석할 수 있게 된다. 5개 리뷰 사이트에서 총 29만7906개의 리뷰를 수집했다. 이후 포스태깅(형태소분석) 작업을 실시했다. 대표적인 한국어 포스태거는 KoNLPy 이다. 그러나 이 예제에서는 김현중 서울대 박사과정이 개발한 cohesion tokenizer를 사용했다. https://github.com/lovit/soy/tree/master/tutorials/soy cohesion tokenizer는 KoNLPy처럼 품사 정보까지는 반환하지 않는다. 하지만 토크나이징을 분석 대상 코퍼스의 출현 빈도를 학습한 결과를 토대로 토큰을 나눠주기 때문에 분석 품질이 좋다. Word2Vec에 KoNLPy 에서 제시하는 품사정보까지 넣을 필요가 없기도 하기때문이다. 어쨌든 cohesion tokenizer로 토크나이징한 결과물은 다음과 같다. 발열,은,LTE,폰,의,숙명,ㅠㅠ HD,촬영,기능,하나,만,으로,도,충분히,만족,하시리,라,봅,니다 이렇게 토크나이징한 결과물을 파이썬 gensim 패키지를 활용해 Word2Vec 방법론을 적용한다. Word2Vec을 적용하는 데는 두 줄만이 필요하다. # Word2Vec embedding from gensim.models import Word2Vec embedding_model\ =Word2Vec(tokenized_contents,size=100,window=2,min_count=50,workers=4,iter=100,sg=1) 포스태깅된 컨텐츠를 100차원의 벡터로 바꾼다. 주변 단어(window)는 앞뒤로 두개까지 보되, 코퍼스 내 출현 빈도가 50번 미만인 단어는 분석에서 제외한다. CPU는 쿼드(4)코어를 쓴다. 100번 반복 학습한다. 분석방법론은 CBOW와 Skip-Gram 중 후자를 선택한다. 벡터로 단어 임베딩이 잘 됐는지 확인해보자. gensim 패키지가 제공하는 기능 중에 ‘most_similar’라는 함수가 있다. 두 단어 벡터 사이의 코사인 유사도를 구해준다. 그 값이 클수록 비슷한 단어라는 뜻이다. 아래 코드는 ‘디자인’이라는 단어와 가장 비슷한(코사인 유사도가 큰) 100개 단어를 출력하라는 코드이다. # check embedding result print(embedding_model.most_similar(positive=["디자인"],topn=100)) Word2Vec 모델이 출력하는 결과는 아래와 같다. 색감, 그립감, 외형, 색깔, UI, 색깔, 각진, 뒷면, 외관… “오 생각보다 괜찮다.” 결과물을 처음 보고 느낀 점이다. 같은 방식으로 ‘사운드’도 해봤습니다. 오디오, 음장, 음질, 퀄리티, 헤드, MP3, 스피커… 역시 굿이다. @ 단어벡터로 가중치 행렬 만들기 우리가 하고 싶은 작업은 이것이다. 문맥적 정보가 보존된 상태의 단어 벡터들 사이의 거리(유사도)를 구한다. 이를 가중치로 이용하여 각 문장별에 대한 스코어를 구한다. 이렇게 구한 스코어를 바탕으로 각 리뷰 문장을 특정 클래스(기능)에 분류한다. @ Word2Vec의 아웃풋은 아래와 같은 한단어에 대한 여러 벡터로 구성되는 행이 여러개 있는 행렬이다. 첫번째 열의 각 요소는 위의 코드 가운데 ‘min_count’ 조건을 만족하는 코퍼스 내 모든 단어가 됩니다. 아래 행렬의 열의 개수는 ‘‘임베딩 차원수(size, 한단어가 100차원 벡터) + 1(문자단어(배터리, 발열,...)이 속한 열)’이 된다. 행렬 각 요소의 숫자들은 사람이 이해하기 어렵습니다. 왜냐하면 100차원 벡터공간의 좌표값들이기 때문이다 - V1 V2 V3 … 배터리 0.1256 0.2211 0.5473 … 발열 0.2385 0.7562 0.8754 … 은 0.2845 0.1293 0.9483 … … … … … … 위의 행렬을 사람이 이해하기 편하게 거리행렬(distance matrix)로 바꿔볼수 있다. 거리를 재는 방식은 다양하다. 일단은 가장 친숙한 유클리디안 방법을 써보겠다. 직각삼각형의 너비와 높이를 알면 피타고라스 정리에 의해 빗변의 길이를 구할 수 있다. 이 식을 사용해 100차원 공간 안에 있는 벡터들 사이의 길이를 쟬 수 있다. 이렇게 구한 거리행렬은 아래와 같다. - 배터리 발열 은 … 배터리 0 1 10 … 발열 1 0 8 … 은 10 8 0 … … … … … … 설명의 편의를 위해 임의의 숫자를 적었다. 위의 거리행렬이 의미하는 바는 이렇다. ‘배터리’와 ‘배터리’ 사이의 거리는 정확하게 일치하기 때문에 0이다. 마찬가지로 ‘발열’과 ‘발열’, ‘은’과 ‘은’ 거리도 0이다. 이런 방식으로 거리행렬의 모든 대각성분은 0이 된다. 한편 예시에서는 ‘배터리’와 ‘발열’ 사이의 거리가 1, ‘배터리’와 ‘은’은 10으로 나왔다. 그렇다면 ‘은’보다는 ‘발열’이 ‘배터리’와 유사한 단어라고 볼 수 있다. 이것이 우리가 만들 가중치 행렬이 지향하는 핵심 원리이다. 즉, 특정 쿼리 단어(예를 들어 ‘배터리’)와 거리가 가까운(=의미가 유사한) 단어는 높은 가중치를 가지도록 가중치 행렬을 만드는 것이 목표이다. 의미가 유사하지 않은 단어는 낮은 가중치를 가지도록 가중치행렬을 만드는것이 목표이다. 이를 수식으로 나타내면 다음과 같습니다. $$$W_{ij}=e^{(-\frac{d(x_{i},x_{j})^{2}}{2\sigma^{2}})}$$$ 왜 이렇게 복잡한 수식을 쓰냐고요? 통계학을 전공한 사람이라면 한눈에 알아보겠지만, exp 앞의 계수를 제외하면 이는 정규분포(normal distribution) 식과 같다. 정규분포는 연속 확률 분포의 일종이다. 수많은 자연, 사회현상을 설명하는 데 탁월한 분석도구로 정평이 나 있다. 위 식 지수의 분자의 d는 거리행렬에서 ‘거리’를 의미한다. 즉 0에서 $$$\infty$$$ 범위를 지니는 들쭉날쭉한 벡터간 거리들을 예쁜 모양의 정규분포로, 그것도 특정 범위로 스케일링까지 해서 반환한다는 얘기이다. 거리행렬에다가 위 수식을 적용한 행렬에서 우리가 원하는 특정 쿼리 단어(예를 들어 ‘배터리’와 ‘사운드’)만 남기고 나머지를 제거한 행렬이 바로 가중치 행렬이 된다. 아래가 최종 결과이다. 다시 한번 가중치행렬의 의미를 곱씹어 보면, 쿼리단어인 ‘배터리’와 의미가 유사한 ‘발열’이라는 단어는 높은 가중치(0.9)를, ‘배터리’와 별 상관이 없는 조사 ‘은’은 낮은 가중치(0.1)를 갖는다. 마찬가지로 ‘사운드’ 기준으로 보면 이와 관련이 높은 ‘음질’이라는 단어는 높은 가중치(0.84)를, 그렇지 않은 나머지 단어들은 낮은 가중치를 갖게 됩니다. - 배터리 발열 은 … 음질 … 배터리 1 0.9 0.1 … 0.1 … 사운드 0.1 0.1 0.01 … 0.84 … @ 가중치 행렬로 문장별 스코어 구하기 이제 처음 우리가 풀려고 했던 문제를 다시 떠올보자. 휴대폰 리뷰 문장을 ‘배터리’, ‘카메라’, ‘디자인’, ‘사운드’ 따위의 클래스(기능,범주)로 classification 하려고 한다. 발열,은,LTE,폰,의,숙명,ㅠㅠ 7개 단어로 이뤄진 위 문장의 스코어를 매겨보자. 처음 등장한 단어 ‘발열’의 가중치는 0.9이다. ‘은’은 0.1 이다. 이렇게 문장에 등장한 7개 단어에 해당하는 가중치를 가중치행렬에서 Lookup 방식으로 가져올 수 있다. 7개 단어로 부터 얻어지는 가중치를 모두 더한 값이 이 문장이 ‘배터리’ 기능을 얼마나 중시하는지를 알려주는 지표가 된다. 즉, "배터리 스코어"는 "배터리라는 쿼리 단어"와 "나머지 단어 사이의 가중치들"의 선형결합(linear combination) 이다. 그런데 여기서 문제가 하나 있다. 문장에 등장한 단어 하나하나마다 가중치행렬에서 Lookup 형식으로 가중치들을 가져오는 건 계산상 너무 비효율적이다. 위 문장만 해도 단어가 7개 있으므로 무려 7번이나 Lookup을 해야 한다는 얘기이다. 이를 빠르고 편하게 하는 방법을 알아봐야한다. 이럴 때 단어문서행렬(Term-Document Matrix)가 강력한 힘을 발휘한다. TDM의 행은 ‘단어’, 열은 ‘문서’가 된다. 즉 위 문장을 아래와 같은 행렬로 변환하는 작업이다. - Doc1 Doc2 … 발열 1 0 … 은 1 0 … … … … … 위 행렬을 다음과 같이 해석할 수 있다. Doc1=‘발열,은,LTE,폰,의,숙명,ㅠㅠ’ 일 때, Doc1은 ‘발열’이라는 단어을 가지고 있기 때문에, 발열 행, Doc1 열의 값은 1이 된다. 마찬가지로 은 행, Doc1 열도 1이다. 저의 경우 단어 등장여부를 binary로 TDM을 구축했다. 즉, ‘발열’이라는 단어가 한번 쓰였든 두번 쓰였든 그 값을 1로 했다는 뜻이다. 물론 빈도수 그대로 TDM을 구축해도 될 것이다. @ 자, 이제 거의 다 왔다 TDM과 가중치행렬을 내적(inner product)해주면 문장별로 스코어를 한방에 구할 수 있다. 우선 말뭉치에 등장하는 전체 단어 수가 7개이고, 우리가 조사하고 싶은 기능(클래스)는 f1, f2, f3 이렇게 세 가지가 있다고 가정해보겠다. 두번째와 여섯번째 단어로 구성된 리뷰의 각 기능별 스코어는 다음과 같다. img 59dbc46d-a779-4322-b331-0635e0bd657c 보시다시피 기능별 스코어는 TDM에서 1에 해당하는 위치의 가중치행렬 열벡터를 참조(Lookup)해서, 이를 기능별로 따로 합산하는 방식으로 계산하게 됩니다. 이를 전체 리뷰로 확장하게 되면 전체 내적의 결과는 (쿼리 단어의 수 x 문서의 수) 행렬 형태가 된다. 즉, Doc1의 ‘배터리’ 스코어가 이 전체 스코어행렬의 1행 1열에 해당하는 요소가 되는 것이다. 만약 쿼리 단어를 ‘배터리’뿐 아니라 ‘사운드’, ‘카메라’ 등까지 지정했다면, 같은 방식으로 Doc1의 ‘사운드’ 스코어는 2행 1열, Doc1의 ‘카메라’ 스코어는 3행 1열이 된다. 마찬가지로 Doc2의 ‘배터리’, ‘사운드’, ‘카메라’ 스코어는 1행 2열, 2행 2열, 3행 3열이 됩니다. @ 파일럿 실험 결과 휴대폰 리뷰 29만7906개를 위와 같은 방식으로 스코어를 매겼다. 임의로 선정한 쿼리 단어는 ‘디자인’, ‘화면’, ‘음질’, ‘스펙’, ‘촬영’, ‘운영체제’, ‘배터리’ 총 7개이다. 위의 챕터에도 설명했듯 각 리뷰별로 쿼리단어 수(위의 경우엔 7개)에 해당하는 스코어들이 나온다. 여기서 가장 높은 값을 지닌 스코어에 해당하는 쿼리단어를 해당 리뷰가 중시하는 기능으로 분류했다. 결과(각 기능별 스코어 상위 5개)는 아래와 같습니다. 배터리 케이스 끼웠고요. 발열은 액정위에서 일어나는겁니다. ls 전자꺼 사용 중인데 충전 잘 되네요... 하지만 무선충전에 단점 발열 ㅠㅠ 근데 진짜 꼽을게..............발열뿐 아이패드2는 정말... 발열이라는 것을 몰랐는데... 베가레이서3은진짜 발열,베터리만좋으면 짱인데 촬영 갤럭시S 2 사진 촬영/ 동영상 촬영 촬영은 기존에 사용중인 SKT 갤투로 찰칵~ 전 카메라 화질과 720p 촬영이 중요한데 어떨런지 3d 촬영이요 헉 그렇게 무겁나요;;;;3D로 영상촬영도 된다던데;;; 잘 나오려나;; 디자인 제가 코 파다 피나면 저 색깔 나오는데.. 아침에 똥 누다가도 가끔 나와요.. 그래서 웬지 친근한 색감 액정색깔차이만 눈에 들어오네요 이거 궁금해서 `색상` `색깔`로 한번씩 검색하니 많이 나오더라구요 미치도록 선명한 대화면 액정과 완전 편리한 UI 아몰레드에 푹 빠져봅시다!! 삼성 핸드폰은 기능은 다 좋은거같은데 ........... 색깔 드럽게 못뽑는다는 .... 화면 갤3 화면 액정이 나갔는지.. 이상한 화면이 뜨는데요... 액정 화면은 몇 인치 인가요? 갤럭시 s3 흰색 화면 잔상 사진만 봐서는 갤스2 화면이 더 좋아보이네요. 갤스는 푸르딩딩한게 촌티나는 색상같아요 아무래도 화면밝기 낮추면 조금이라도 더 버텨주겠죠?ㅋㅋ 운영체제 결국은 운영체제에 따라 갈릴듯. 운영체제가 다르니 비교하기 그렇죠 운영체제가... 달라서.. 운영체제가 쉣이었음 단일 운영체제 바다는 왜 그 모양인가요... 사운드 아레나에서도 이렇게 평했군요. 정말 음질 표현을 너무 잘했네욬ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 음질은안드에서상급이죠 ㅎㅎ 음질은 좋았으니.. 잭꽃아야되지만: 음질은... 제가 막귀라서. 핸드폰 음질 다 똑같은거 아닌가요? 스피커는 저도 공감 ㅋㅋㅋㅋ 음질은 먹는건가여 수준 스펙 스펙으로만 따져도 옴냐2보다 아이폰이 훨씬 성능이 좋을텐데요... ^^;; 갤투가 하드웨어 스펙이 좋죠 그래서 갤투 이제 os도 같고 그렇군요... 하긴 하드웨어 스펙도 더 낫구 ㅠㅠ 갤럭시는 나올때마다 스펙종결수준이니까요..ㅎㅎ 삼성 스펙만 쩔지... 벤치는 믿을게 못될듯하오 @ 마치며 이상으로 Word2Vec을 활용한 문장 분류 방법을 알아보았다. 이 프레임워크의 사용 과정을 요약하면 다음과 같다. 1. TDM을 구축한다. 1. Word2Vec 기반으로 가중치매트릭스를 생성한다. img 9644dd28-d473-45b5-9edf-3b54649bebb3 1. 위와 같이 구축한 가중치매트릭스와 TDM을 내적해 스코어를 산출한다. img c2003319-9790-4e3b-8499-4ffeee713cb7 @ 이미 눈치 채셨겠지만 어떤 문서가 특정 쿼리 단어와 얼마나 연관성이 있는지 스코어를 낼 수 있다. 바꿔 말하면 쿼리 단어를 어떻게 선정하느냐에 따라 다양한 문장분류기를 만들어낼 수 있다는 얘기이다.